package com.test.auth_db_auto.auth_sms;

import com.alibaba.druid.util.StringUtils;
import com.test.auth_db_auto.exception.VerificationCodeFailureException;
import com.test.auth_db_auto.support.BootSecurityProperties;
import com.test.auth_db_auto.utils.RedisUtil;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @ Author: .Mr
 * @ ClassName SmsCodeCheckFilter
 * @ Description TODO
 * @ date 2022/1/5 10:23
 * @ Version 1.0
 * 手机号短信登录校验过滤
 */
@Getter
@Setter
public class SmsCodeCheckFilter extends OncePerRequestFilter {

    /**
     * 验证码校验失败处理器
     */
    @Autowired
    private AuthenticationFailureHandler failureHandler;
    private BootSecurityProperties properties;
//    private StringRedisTemplate template;
    private AuthenticationSuccessHandler successHandler;
    private UserDetailsService userDetailsService;
    /**
     *  验证请求url与配置的url是否匹配的工具类
     * */
    private PathMatcher pathMatcher;

   public SmsCodeCheckFilter(BootSecurityProperties properties){
        this.properties=properties;
        this.pathMatcher=new AntPathMatcher();
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String loginUrl=this.properties.getSmsLogin().getLoginProcessUrl();
        if(this.pathMatcher.match(loginUrl,request.getRequestURI())
            && StringUtils.equalsIgnoreCase(request.getMethod(),"post")){
            try{
                check(request,response,filterChain);
            }catch (Exception e){
                if(e instanceof VerificationCodeFailureException){
                    failureHandler.onAuthenticationFailure(request,response,(AuthenticationException)e);
                }
                throw e;
            }
        }else{
            filterChain.doFilter(request,response);
        }
    }


    private void check(HttpServletRequest request,HttpServletResponse response,FilterChain chain) throws IOException, ServletException {
        String mobile=request.getParameter(properties.getSmsLogin().getMobileParameterName()); //获取手机号
        String code=request.getParameter(properties.getSmsLogin().getCodeParameterName());  //获取验证码
        String password=request.getParameter(properties.getSmsLogin().getPasswordParameterName()); //获取密码

        if(mobile==null||mobile.trim().length()==0){
            throw new VerificationCodeFailureException("手机号不允许为空");
        }
        //没有密码代表用户为旧用户
        if(password==null||password.trim().length()==0){
            if(!RedisUtil.hasKey(mobile)){
                throw new VerificationCodeFailureException("验证码过期或手机号错误");
            }

            long expireTime=RedisUtil.getExpire(mobile);
            if(expireTime<=0){
                throw new VerificationCodeFailureException("验证码过期");
            }

            String redisCode=RedisUtil.get(mobile).toString();

            if(!code.equals(redisCode)){
                throw new VerificationCodeFailureException("验证码错误");
            }

        }else{  //新用户，现在设置密码

        }
        chain.doFilter(request,response);
   }

}
